import java.util.concurrent.*;

/**
 * 线程池：
 *  减少每次创建线程的消耗，节约资源；会一直存在，消耗内存，需要shutdown
 *  Executors：线程池的工具类（不推荐使用这个创建池，会造成oom）
 *  ThreadPoolExecutor：底层使用的该类进行创建线程池（推荐使用，能够根据我们自己的业务需求定制）
 *
 *  ThreadPoolExecutor 7个参数：
 *      corePoolSize：核心线程数，任务来了就创建，核心线程数不会被销毁，除了shutdown()销毁线程池
 *      workQueue：工作队列，核心线程数满了就往队列里面添加任务
 *      maximumPoolSize：最大的线程数，工作队列满了就创建
 *      RejectedExecutionHandler：maximumPoolSize满了就采用拒绝策略
 *      keepAliveTime：大于corePoolSize那部分在改时间内没有任务，就会被销毁
 *      TimeUnit：时间单位
 *      ThreadFactory：默认，线程工厂
 */
public class ExcuterDemo {

    public static void main(String[] args) {

        // 创建2个线程的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        // 带有缓存的线程池，无限个线程
        ExecutorService executorService1 = Executors.newCachedThreadPool();
        // 单线程池
        ExecutorService executorService2 = Executors.newSingleThreadExecutor();

        // 不带返回值execute()
        // 带返回值submit()
        try {
            for (int i = 0; i < 3; i++) {
//            executorService.execute(()->{
//                System.out.println(Thread.currentThread().getName()+"线程执行任务");
//            });
//            executorService1.execute(()->{
//                System.out.println(Thread.currentThread().getName()+"线程执行任务");
//            });
                executorService2.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"线程执行任务");
                });
            }
        }catch (Exception e){

        }finally {
            // 关闭线程池
            executorService2.shutdown();
        }

        System.out.println(Thread.currentThread().getName()+"执行完成");
    }
}

/**
 * 自定义线程池
 * 怎么合理配置线程数：
 *  1：cpu
 *      看cpu核数，核数+1为max线程数
 *  2：IO
 *      a:cpu核数*2
 *      b:cpu核数/(1 - 阻变数（0.8~0.9之间）)
 */

class MyThreadPool{


    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 2L, TimeUnit.SECONDS, new LinkedBlockingDeque(3),new ThreadPoolExecutor.DiscardOldestPolicy());
        try {
            for (int i = 0; i < 11; i++) {
                threadPoolExecutor.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "，执行任务");
                });
            }
        }catch (Exception e){
            System.out.println(e);
        }finally {
            threadPoolExecutor.shutdown();
        }

    }


}








